﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2013-03-21 20:07:26Z</CreationDate>
</File>
*/
#endregion

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

using Outcoder.Reflection;

namespace Outcoder.UserOptionsModel
{
	public class ListOption<TSetting> : UserOptionBase<TSetting>, IListOption<TSetting>, IProvider<IUserOptionReaderWriter>
	{
		/* TODO: [DV] Comment. */
		public ListOption(
			Func<string> titleFunc,
			string settingKey,
			Func<TSetting> defaultValueFunc,
			List<Func<TSetting>> options)
			: base(titleFunc, settingKey, defaultValueFunc)
		{
			ArgumentValidator.AssertNotNull(options, "options");
			SetOptions(options);

			SetDefaultTemplateName();
		}

		public ListOption(
			Func<string> titleFunc,
			string settingKey,
			Func<TSetting> defaultValueFunc,
			List<TSetting> options)
			: base(titleFunc, settingKey, defaultValueFunc)
		{
			ArgumentValidator.AssertNotNull(options, "options");

			foreach (var pair in options)
			{
				this.options.Add(pair);
			}

			SetDefaultTemplateName();
		}

		void SetDefaultTemplateName()
		{
			var settingType = typeof(TSetting);
			if (settingType.IsEnum())
			{
				TemplateNameFunc = () => "Enum";
			}
			else
			{
				TemplateNameFunc = () => typeof(TSetting).Name;
			}
		}

		public void SetOptions(IEnumerable<Func<TSetting>> optionFuncs)
		{
			ArgumentValidator.AssertNotNull(optionFuncs, "optionFuncs");

			options.Clear();

			foreach (var optionFunc in optionFuncs)
			{
				if (optionFunc == null)
				{
					throw new ArgumentException("Option func cannot be null.");
				}

				TSetting resolvedValue = optionFunc();
				options.Add(resolvedValue);
			}
		}

		public void SetOptions(IEnumerable<TSetting> optionValues)
		{
			ArgumentValidator.AssertNotNull(optionValues, "optionValues");

			options.Clear();

			foreach (var optionValue in optionValues)
			{
				options.Add(optionValue);
			}
		}

		ObservableCollection<TSetting> options = new ObservableCollection<TSetting>();

		public ObservableCollection<TSetting> Options
		{
			get
			{
				return options;
			}
			private set
			{
				options = value;
			}
		}

		public IUserOptionReaderWriter ProvidedItem
		{
			get
			{
				return new ListOptionReaderWriter<TSetting>(this);
			}
		}
	}
}